package com.logic.modular.game.battle.process.battleStage;

import com.logic.modular.game.battle.panel.Battle;
import com.logic.modular.game.battle.panel.attribute.domain.EffectStatus;
import com.logic.modular.game.battle.panel.attribute.domain.PlayerHeroAttribute;
import com.logic.modular.game.battle.panel.attribute.PlayerHeroAttributeServiceImpl;
import com.logic.modular.game.battle.panel.skillEffect.PvpSkillEffect;
import com.logic.modular.game.battle.panel.skillEffect.PvpSkillEffectServiceImpl;
import com.logic.modular.game.battle.process.domain.BattleInfo;
import com.logic.modular.game.battle.process.domain.BattleRoundInfo;
import com.logic.modular.game.battle.process.domain.EffectTriggerInfo;
import com.logic.modular.game.battle.process.domain.PreRoundActionInfo;

import com.logic.modular.game.battle.process.skillEffectHandle.skillEffectSelect.SkillEffectTriggerHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 回合前准备
 */
@Slf4j
@Service
public class PreparationStageOfRoundService {
    @Resource
    private PvpSkillEffectServiceImpl skillEffectService;
    @Resource
    private PlayerHeroAttributeServiceImpl playerHeroAttributeService;


    /**
     * 回合前准备阶段
     *
     * @param battleUUID 战斗id
     */
    public BattleRoundInfo apply(
            String battleUUID
    ) {
        PreRoundActionInfo preRoundActionInfo = new PreRoundActionInfo();
        List<PlayerHeroAttribute> sidesSurvivalHeroList = playerHeroAttributeService.obtainSurvivalHeroList(battleUUID);
        Battle battle = Battle.get(battleUUID);
        Long battleId = battle.getBattleId();
        BattleInfo battleInfo = BattleInfo.selectCache(battleId);


        skillEffectService.list(battleId).forEach(skillEffect -> {
            skillEffect.status.setNumberOfTriggersThisRound(0);
            skillEffectService.saveCache(skillEffect);
        });

        log.info("=======所有武将进入回合准备阶段");
        for (PlayerHeroAttribute playerHero : sidesSurvivalHeroList) {
            PlayerHeroAttribute playerHeroAttribute = playerHeroAttributeService.get(battleUUID, playerHero.getId());
            playerHeroAttribute.setPhase(20);
            playerHeroAttributeService.saveCache(playerHeroAttribute);
        }
        // 尝试触发被动战法
        Map<String, List<PvpSkillEffect>> collect2 = skillEffectService.obtainSkillEffects(battleId, 2);
        collect2.forEach((k, v) -> {
            log.info("刷新被动战法:{}", k);
            List<PvpSkillEffect> pvpSkillEffects = SkillEffectTriggerHandle.applyNewSkillEffect(v);
            List<EffectTriggerInfo> collect = pvpSkillEffects.stream()
                    .map(PvpSkillEffect::getSkillEffectTriggerInfo)
                    .collect(Collectors.toList());
            log.info("触发信息{}", collect);
            preRoundActionInfo.skillTrigger2.addAll(collect);
        });

        // 尝试触发指挥战法
        Map<String, List<PvpSkillEffect>> collect3 = skillEffectService.obtainSkillEffects(battleId, 3);
        collect3.forEach((k, v) -> {
            log.info("刷新指挥战法:{}", k);
            List<PvpSkillEffect> pvpSkillEffects = SkillEffectTriggerHandle.applyNewSkillEffect(v);
            List<EffectTriggerInfo> collect = pvpSkillEffects.stream()
                    .map(PvpSkillEffect::getSkillEffectTriggerInfo)
                    .collect(Collectors.toList());
            log.info("触发信息{}", collect);
            preRoundActionInfo.skillTrigger3.addAll(collect);
        });
        BattleRoundInfo battleRoundInfo = new BattleRoundInfo();
        battleRoundInfo.setPreRoundActionInfo(preRoundActionInfo);
        battleInfo.battleRound.put(battle.getRound(), battleRoundInfo);
        battleInfo.saveCache();
        return battleRoundInfo;
    }

    /**
     * 获取行动武将
     * 先手状态 > 先手值高
     */
    public List<PlayerHeroAttribute> obtainActHeroList(
            @NotNull(message = "战斗id不能为空") String battleUUID
    ) {
        try {
            return playerHeroAttributeService.listCache(battleUUID).stream()
                    .filter(item -> item != null && item.getCurrentForce() > 0)
                    .sorted((o1, o2) -> {
                        Map<Long, EffectStatus> statusMap1 = o1.getStatus();
                        Map<Long, EffectStatus> statusMap2 = o2.getStatus();

                        EffectStatus speed1 = statusMap1 != null ? statusMap1.get(36L) : null;
                        EffectStatus speed2 = statusMap2 != null ? statusMap2.get(36L) : null;

                        Double speedValue1 = o1.getSpeed();
                        Double speedValue2 = o2.getSpeed();

                        int back;
                        if (speed1 != null && speed2 == null) {
                            back = -1; // o1 优先
                        } else if (speed1 == null && speed2 != null) {
                            back = 1; // o2 优先
                        } else { // 同时拥有状态或者没有状态
                            back = speedValue1.compareTo(speedValue2);
                        }
                        return back;
                    })
                    .collect(Collectors.toList());
        } catch (Exception e) {
            // 记录日志或处理异常
            log.error("获取行动武将异常", e);
            return Collections.emptyList();
        }
    }
}
